package main;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;
import java.util.Date;

import javax.media.opengl.GLCanvas;
import model.MainModel;

import com.sun.opengl.util.Animator;

import graphics.engine.*;


public class MainWindow {

	private static Frame frame;
	private static GLCanvas leftCanvas;
	private static GLCanvas rightCanvas;
	private static TimeLine timeLine;
	private static Animator animator;
	private static MainModel model;
	
	public static void main(String[] args) 
	{
		MainWindow.model = new MainModel();
		
		Date launchTime = new Date(System.currentTimeMillis());
		GridBagLayout layout = new GridBagLayout();
		
		frame = new Frame("FloorPlan NodeLink Hybrid Prototype");
		frame.setLayout(layout);
		
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 3;
		c.gridheight = 1;
		c.weightx = 1.0f;
		c.weighty = 1.0f;

		timeLine = new TimeLine(new Date(System.currentTimeMillis()), new Date(model.minTime), new Date(model.maxTime ));
			
		frame.add(timeLine, c);
		
		c = new GridBagConstraints();
		c.fill = GridBagConstraints.VERTICAL;
		c.anchor = GridBagConstraints.EAST;
		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 1;
		c.weighty = 1;
		c.gridwidth = 1;
		c.gridheight = 1;
		
		TargetGrid grid = new TargetGrid(model.targets);
		grid.setSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
		grid.setMinimumSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
		grid.setPreferredSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
		
		frame.add(grid,c);


		
		leftCanvas = new GLCanvas();
		RenderEngine leftRenderEngine;
		
		
		if(Settings.IsHybrid)
		{
			c = new GridBagConstraints();
			c.fill = GridBagConstraints.BOTH;
			c.anchor = GridBagConstraints.EAST;
			c.gridx = 1;
			c.gridy = 0;
			c.weightx = 1;
			c.weighty = 1;
			c.gridwidth = 2;
			c.gridheight = 1;
			leftRenderEngine = new RenderEngine(model, RenderEngineType.Hybrid, timeLine, launchTime);
		}
		else
		{		
			c = new GridBagConstraints();
			c.fill = GridBagConstraints.BOTH;
			c.anchor = GridBagConstraints.EAST;
			c.gridx = 1;
			c.gridy = 0;
			c.weightx = 0.5;
			c.weighty = 1;
			c.gridwidth = 1;
			c.gridheight = 1;
			leftRenderEngine = new RenderEngine(model, RenderEngineType.FloorPlan, timeLine, launchTime);
		}
		
		leftCanvas.addGLEventListener(leftRenderEngine);
		leftCanvas.addKeyListener(leftRenderEngine.getKeyboardControler());
		leftCanvas.addMouseListener(leftRenderEngine.getMouseControler());
		leftCanvas.addMouseMotionListener(leftRenderEngine.getMouseControler());
		leftCanvas.addMouseWheelListener(leftRenderEngine.getMouseControler());

		frame.add(leftCanvas, c);
		
		if(!Settings.IsHybrid)
		{
			c = new GridBagConstraints();
			c.fill = GridBagConstraints.BOTH;
			c.anchor = GridBagConstraints.EAST;
			c.gridx = 2;
			c.gridy = 0;
			c.weightx = 0.5;
			c.weighty = 1;
			c.gridwidth = 1;
			
			rightCanvas = new GLCanvas();
			RenderEngine rightRenderEngine = new RenderEngine(model, RenderEngineType.NodeLink, timeLine, launchTime);
			
			rightCanvas.addGLEventListener(rightRenderEngine);
			rightCanvas.addKeyListener(rightRenderEngine.getKeyboardControler());
			rightCanvas.addMouseListener(rightRenderEngine.getMouseControler());
			rightCanvas.addMouseMotionListener(rightRenderEngine.getMouseControler());
			rightCanvas.addMouseWheelListener(rightRenderEngine.getMouseControler());
			
			frame.add(rightCanvas, c);
			
		}

		animator = new Animator(leftCanvas);
		
		frame.addWindowListener(new WindowAdapter() 
		{
			public void windowClosing(WindowEvent e)
			{
				new Thread(new Runnable() 
				{
					public void run() 
					{
						animator.stop();
						System.exit(0);
					}
				}).start();
			}
		});
		
		frame.setExtendedState(Frame.MAXIMIZED_BOTH);
		frame.setState(Frame.MAXIMIZED_BOTH);
		frame.setVisible(true);
		
		 
		if(!Settings.IsHybrid)
		{
			animator.add(rightCanvas);
		}
	    animator.start();
		frame.setVisible(true);
	    
	}
}